package cos480.amiwsd;

/**
 *  PSST.lex
 *  
 *  Generates a lexer for tokenizing PSST input.
 * 
 *  @author Emma Strubell
 *  @author Will Lamond
 *  COS480 - Chawathe
 *  December 1, 2011
 */

import java_cup.runtime.*;
import java.io.IOException;
import cos480.amiwsd.PSSTSym;

%%

%class PSSTLex
%unicode
%line
%column
%final
%cupsym cos480.amiwsd.PSSTSym
%cup

%state USER, PASS, STRINPUT, IPADDRINPUT

%{
	StringBuffer userpass = new StringBuffer();
	StringBuffer strInput = new StringBuffer();
	/*StringBuffer ipAddr = new StringBuffer();*/
	
	private Symbol sym(int type){
		return sym(type, yytext());
	}

	private Symbol sym(int type, Object value){
		return new Symbol(type, yyline, yycolumn, value);
	}

	private void error() throws IOException{
		throw new IOException(
		"illegal text at line = "+yyline+", column = "+yycolumn+", text = '"+yytext()+"'");
	}
%}

lineterminator	= \r|\n|\r\n
whitespace		= {lineterminator}|[ \t\f]

/* A valid Java identifier:
 * Character.isJavaIdentifierStart(jletter) == true
 * Character.isJavaIdentifierPart(jletterdigit) == true
 */
identifier	= [:jletter:][:jletterdigit:]*

integer   = [0-9][0-9]*
doub	  = [-+]?[0-9][0-9]*((\.[0-9][0-9]*)|(\.[0-9][0-9]*[eE][-+]?[1-9][0-9]*))?

version   = ([0-9][0-9]*\.)?([0-9][0-9]*\.)?[0-9][0-9]*
date	  = [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
time	  = [0-9][0-9]:[0-9][0-9]:[0-9][0-9]
/*timestamp = [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\s+[0-9][0-9]:[0-9][0-9]:[0-9][0-9]  
*/	

%%

/* functions */
"get"				{return sym(PSSTSym.GET);}
"gen"				{return sym(PSSTSym.GEN);}
"search"			{return sym(PSSTSym.SEARCH);}
"add"				{return sym(PSSTSym.ADD);}


/* various punctuation */
","					{return sym(PSSTSym.COM);}
";"					{return sym(PSSTSym.SEMI);}
":"					{return sym(PSSTSym.COLON);}

"as"				{return sym(PSSTSym.AS);}
"from"				{return sym(PSSTSym.FROM);}
"define"			{return sym(PSSTSym.DEFINE);}
"landscape"			{return sym(PSSTSym.LAND);}
"instance"			{return sym(PSSTSym.INST);}				
"ips"				{return sym(PSSTSym.IPS);}
"simResults"		{return sym(PSSTSym.SIM);}
"params"			{return sym(PSSTSym.PARAMS);}
"all"				{return sym(PSSTSym.ALL);}
"hhnum" 			{return sym(PSSTSym.HHNUM);}
"method"			{return sym(PSSTSym.METHOD);}
"never"				{return sym(PSSTSym.NEVER);}

"simple"			{return sym(PSSTSym.METHODTYPE, yytext());}
"and"				{return sym(PSSTSym.AND, yytext());}

"mu" 				{return sym(PSSTSym.MU);}
"phi"	 			{return sym(PSSTSym.PHI);}
"gamma" 			{return sym(PSSTSym.GAMMA);}
"landID"			{return sym(PSSTSym.LANDID);}
"simType" 			{return sym(PSSTSym.SIMTYPE);}
"minTime" 			{return sym(PSSTSym.MINTIME);}
"maxTime" 			{return sym(PSSTSym.MAXTIME);}
"I0"	 			{return sym(PSSTSym.I0);}
"CRnum"	 			{return sym(PSSTSym.CRNUM);}
"instanceID"		{return sym(PSSTSym.INSTID);}
"numSims"			{return sym(PSSTSym.NUMSIMS);}
"p0"				{return sym(PSSTSym.P0);}
"p1"				{return sym(PSSTSym.P1);}
"p2"				{return sym(PSSTSym.P2);}

"result"			{return sym(PSSTSym.RESULT);}
"scanResults"		{return sym(PSSTSym.SCANRESULTS);}
"ip:"				{
						/* to avoid collisions with double, int */
						/*ipAddr.setLength(0);*/
						yybegin(IPADDRINPUT);
					}

"software"			{return sym(PSSTSym.SOFTWARE);}
"success"			{return sym(PSSTSym.SUCCESS);}
"before"			{return sym(PSSTSym.BEFORE);}
"after"				{return sym(PSSTSym.AFTER);}
"between"			{return sym(PSSTSym.BETWEEN);}
"filename"			{return sym(PSSTSym.FILENAME);}
"desc"				{return sym(PSSTSym.DESC);}
"dateCreated"		{return sym(PSSTSym.DATECREATED);}
"scanDate"			{return sym(PSSTSym.SCANDATE);}
"scanned"			{return sym(PSSTSym.SCANNED);}

"years"				{return sym(PSSTSym.YEARS);}
"months"			{return sym(PSSTSym.MONTHS);}
"days"				{return sym(PSSTSym.DAYS);}
"weeks"				{return sym(PSSTSym.WEEKS);}

//{integer}" years"	{return sym(PSSTSym.INTERVAL, yytext());}
//{integer}" months"	{return sym(PSSTSym.INTERVAL, yytext());}
//{integer}" days"	{return sym(PSSTSym.INTERVAL, yytext());}
//{integer}" weeks"	{return sym(PSSTSym.INTERVAL, yytext());}

/* connection stuffffff */
"disconnect"		{return sym(PSSTSym.DISCONNECT);}
"connect "			{
						userpass.setLength(0);
						yybegin(USER);
					}

"SIS"				{return sym(PSSTSym.SIMTYPEVAR, yytext());}
"SIR"				{return sym(PSSTSym.SIMTYPEVAR, yytext());}
"SIRS"				{return sym(PSSTSym.SIMTYPEVAR, yytext());}

[sfeSFE]			{return sym(PSSTSym.SUCCESS_OPTION, yytext());}

<IPADDRINPUT>{
[12]?[0-9]?[0-9](\.[12]?[0-9]?[0-9])?(\.[12]?[0-9]?[0-9])?(\.[12]?[0-9]?[0-9])?	{
					yybegin(YYINITIAL);
					return sym(PSSTSym.IP, yytext());
}}

<STRINPUT>{
	\"			{
					yybegin(YYINITIAL);
					return sym(PSSTSym.STRING, strInput.toString());
				}
	[^\n\r\"]+	{
					strInput.append(yytext());
				}
}

\"				{
					strInput.setLength(0);
					yybegin(STRINPUT);
}
				

<USER>{
[:jletter:][:jletterdigit:]*	{
						userpass.append(yytext());
						yybegin(PASS);
					}
}

<PASS>{
[^\r\n]+			{
						userpass.append(yytext());
						yybegin(YYINITIAL);
						return sym(PSSTSym.CONNECT, userpass.toString());
					}
}




/* an integer */
{integer}	{
		return sym(PSSTSym.INT, yytext());
}

{doub}		{
		return sym(PSSTSym.DOUBLE, yytext());
}


/* a version number */
{version}	{
			return sym(PSSTSym.VERSION, yytext());
		}

/* a date: YYYY-MM-DD*/
{date} {
	return sym(PSSTSym.DATE, yytext());
}

/* a timestamp */ 
/*s
{timestamp} {
	return sym(PSSTSym.TIMESTAMP, yytext());
}
*/

/* identifiers */
{identifier}		{return sym(PSSTSym.IDENTIFIER);}


/* whitespace */
{whitespace}		{/* ignore whitespace */}

/* error */
.|\n				{error();}